package com.atguigu.tingshu.user.service.impl;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.IdUtil;
import com.atguigu.tingshu.album.AlbumFeignClient;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.rabbit.constant.MqConst;
import com.atguigu.tingshu.common.rabbit.service.RabbitService;
import com.atguigu.tingshu.model.user.UserInfo;
import com.atguigu.tingshu.model.user.UserPaidAlbum;
import com.atguigu.tingshu.model.user.UserPaidTrack;
import com.atguigu.tingshu.user.mapper.*;
import com.atguigu.tingshu.user.pattren.DeliveryStrategy;
import com.atguigu.tingshu.user.pattren.factory.StrategyFactory;
import com.atguigu.tingshu.user.service.UserInfoService;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import com.atguigu.tingshu.vo.user.UserPaidRecordVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j
@Service
@SuppressWarnings({"all"})
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {

    @Autowired
    private UserInfoMapper userInfoMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private WxMaService wxMaService;

    @Autowired
    private RabbitService rabbitService;

    @Autowired
    private UserPaidAlbumMapper userPaidAlbumMapper;

    @Autowired
    private UserPaidTrackMapper userPaidTrackMapper;

    @Autowired
    private VipServiceConfigMapper vipServiceConfigMapper;

    @Autowired
    private UserVipServiceMapper userVipServiceMapper;


    @Autowired
    private AlbumFeignClient albumFeignClient;


    /**
     * 微信一键登录
     *
     * @param code
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public HashMap<String, Object> wxLogin(String code) {
        try {
            //根据code获取用户在微信小程序信息的唯一id 查看是否注册过
            //根据code获取用户的唯一标识微信的会话信息储存着用户的唯一id
            WxMaJscode2SessionResult sessionInfo = wxMaService.getUserService().getSessionInfo(code);
            String openId = sessionInfo.getOpenid();

            UserInfo userInfo = baseMapper.selectOne(new LambdaQueryWrapper<UserInfo>().
                    eq(UserInfo::getWxOpenId, openId));

            if (userInfo == null) {
                //进行注册id
                userInfo = new UserInfo();
                userInfo.setWxOpenId(openId);
                userInfo.setNickname("马哈鱼");
                userInfo.setPhone("119");
                userInfo.setAvatarUrl("http://192.168.200.6:9000/tingshu/2025-09-24/cca18ae4-b8f0-4f63-a921-41b3f52482d1/png");
                baseMapper.insert(userInfo);
                //使用rabbitmq的方式进行账户初始化
                Map<String, Object> map = new HashMap<>();
                map.put("userId", userInfo.getId());
                map.put("amount", BigDecimal.valueOf(100));
                map.put("title", "首次登录平台用户赠送100元体验金额");
                map.put("orderNo", "zs" + IdUtil.getSnowflakeNextId());
                //3.2.2 发送消息到MQ
                rabbitService.sendMessage(MqConst.EXCHANGE_ACCOUNT, MqConst.EXCHANGE_USER, map);
            }
            //给前端个响应一个token
            String token = IdUtil.randomUUID();
            String loginKey = RedisConstant.USER_LOGIN_KEY_PREFIX + token;
            UserInfoVo userInfoVo = BeanUtil.copyProperties(userInfo, UserInfoVo.class);
            redisTemplate.opsForValue().set(loginKey, userInfoVo, RedisConstant.USER_LOGIN_KEY_TIMEOUT, TimeUnit.SECONDS);
            HashMap<String, Object> map = new HashMap<>();
            map.put("token", token);
            return map;
        } catch (WxErrorException e) {
            throw new GuiguException(500, "微信登录失败" + e.getMessage());
        }
    }

    @Override
    public UserInfoVo getUserInfo(Long userId) {
        UserInfo userInfo = baseMapper.selectById(userId);
        UserInfoVo userInfoVo = BeanUtil.copyProperties(userInfo, UserInfoVo.class);
        return userInfoVo;
    }

    @Override
    public void updateUser(UserInfoVo userInfoVo, Long userId) {
        UserInfo userInfo = new UserInfo();
        BeanUtil.copyProperties(userInfoVo, userInfo);
        userInfo.setId(userId);
        userInfo.setAvatarUrl(userInfoVo.getAvatarUrl());
        userInfo.setNickname(userInfoVo.getNickname());
        userInfoMapper.updateById(userInfo);
    }

    /**
     * @param userId                     用户的id
     * @param albumId                    专辑的id
     * @param needCheckBuyStatusTrackIds 需要查询的声音的id
     * @return
     */
    @Override
    public Map<Long, Integer> userIsPaidTrack(Long userId, Long albumId, List<Long> needCheckBuyStatusTrackIds) {
        Map<Long, Integer> map = new HashMap<>();
        //1.根据用户ID+专辑ID查询已购专辑记录，如果存在则将待检查声音购买状态设为1
        Long count = userPaidAlbumMapper.selectCount(
                new LambdaQueryWrapper<UserPaidAlbum>()
                        .eq(UserPaidAlbum::getUserId, userId)
                        .eq(UserPaidAlbum::getAlbumId, albumId)
        );
        if (count > 0) {
            for (Long trackId : needCheckBuyStatusTrackIds) {
                map.put(trackId, 1);
            }
            return map;
        }

        //2.根据用户ID+专辑ID查询已购声音记录，如果不存在则将待检查声音购买状态设为0
        List<UserPaidTrack> userPaidTrackList = userPaidTrackMapper.selectList(
                new LambdaQueryWrapper<UserPaidTrack>()
                        .eq(UserPaidTrack::getUserId, userId)
                        .eq(UserPaidTrack::getAlbumId, albumId)
                        .select(UserPaidTrack::getTrackId)
        );
        if (CollUtil.isEmpty(userPaidTrackList)) {
            for (Long trackId : needCheckBuyStatusTrackIds) {
                map.put(trackId, 0);
            }
            return map;
        }

        //3.如果存在声音购买记录，找出已购买声音ID购买状态设为1，未购买设置为0
        List<Long> userPaidTrackIdList = userPaidTrackList
                .stream()
                .map(UserPaidTrack::getTrackId)
                .collect(Collectors.toList());

        for (Long trackId : needCheckBuyStatusTrackIds) {
            if (userPaidTrackIdList.contains(trackId)) {
                map.put(trackId, 1);
            } else {
                map.put(trackId, 0);
            }
        }
        return map;
    }

    @Override
    public Boolean isPaidAlbum(Long userId, Long albumId) {
        Long count = userPaidAlbumMapper.selectCount(
                new LambdaQueryWrapper<UserPaidAlbum>()
                        .eq(UserPaidAlbum::getUserId, userId)
                        .eq(UserPaidAlbum::getAlbumId, albumId)
        );
        return count > 0;
    }

    @Override
    public List<Long> findUserPaidTrackList(Long userId, Long albumId) {

        List<UserPaidTrack> userPaidTracks = userPaidTrackMapper.selectList(
                new LambdaQueryWrapper<UserPaidTrack>()
                        .eq(UserPaidTrack::getUserId, userId)
                        .eq(UserPaidTrack::getAlbumId, albumId)
                        .select(UserPaidTrack::getTrackId)
        );
        if (CollUtil.isNotEmpty(userPaidTracks)) {
            return userPaidTracks.stream().map(UserPaidTrack::getTrackId).collect(Collectors.toList());
        }
        return null;
    }

    @Autowired
    private StrategyFactory strategyFactory;

    /**
     * 虚拟用户的发货
     *
     * @param userPaidRecordVo
     */
    @Override
    public void savePaidRecord(UserPaidRecordVo userPaidRecordVo) {

        String itemType = userPaidRecordVo.getItemType();
        DeliveryStrategy deliveryStrategy = strategyFactory.getDeliveryStrategy(itemType);
        deliveryStrategy.delivery(userPaidRecordVo);


//        if (SystemConstant.ORDER_ITEM_TYPE_ALBUM.equals(userPaidRecordVo.getItemType())) {
//            //1. 判断订单是否已经被处理
//            //1.1 为用户发放权益
//            Long count = userPaidAlbumMapper.selectCount(
//                    new LambdaQueryWrapper<UserPaidAlbum>()
//                            .eq(UserPaidAlbum::getOrderNo, userPaidRecordVo.getOrderNo())
//            );
//            if (count > 0) {
//                return;
//            }
//            //2.新增订单记录即可
//            UserPaidAlbum userPaidAlbum = new UserPaidAlbum();
//            userPaidAlbum.setOrderNo(userPaidRecordVo.getOrderNo());
//            userPaidAlbum.setUserId(userPaidRecordVo.getUserId());
//            userPaidAlbum.setAlbumId(userPaidRecordVo.getItemIdList().get(0));
//            userPaidAlbumMapper.insert(userPaidAlbum);
//        } else if (SystemConstant.ORDER_ITEM_TYPE_TRACK.equals(userPaidRecordVo.getItemType())) {
//            //2. 判断声音是否被购买过
//            Long count = userPaidTrackMapper.selectCount(
//                    new LambdaQueryWrapper<UserPaidTrack>()
//                            .in(UserPaidTrack::getOrderNo, userPaidRecordVo.getOrderNo())
//            );
//            if (count > 0) {
//                return;
//            }
//            //2.1 为用户发放权益
//            TrackInfo trackInfo =
//                    albumFeignClient.getTrackInfo(userPaidRecordVo.getItemIdList().get(0)).getData();
//            Long albumId = trackInfo.getAlbumId();
//            //2.3 新增订单记录即可
//            userPaidRecordVo.getItemIdList().stream().forEach(itemId ->
//                    {
//                        UserPaidTrack userPaidTrack = new UserPaidTrack();
//                        userPaidTrack.setOrderNo(userPaidRecordVo.getOrderNo());
//                        userPaidTrack.setUserId(userPaidRecordVo.getUserId());
//                        userPaidTrack.setTrackId(itemId);
//                        userPaidTrack.setAlbumId(albumId);
//                        userPaidTrackMapper.insert(userPaidTrack);
//                    }
//            );
//
//        } else if (SystemConstant.ORDER_ITEM_TYPE_VIP.equals(userPaidRecordVo.getItemType())) {
//            //3. 判断当前订单是否被处理
//            Long count = userVipServiceMapper.selectCount(
//                    new LambdaQueryWrapper<UserVipService>()
//                            .eq(UserVipService::getOrderNo, userPaidRecordVo.getOrderNo())
//            );
//            if (count > 0) {
//                return;
//            }
//            //3.1 为用户发放权益
//            //3.1.1 查询当前用户是否为vip
//            Boolean isVip = false;
//            UserInfoVo userInfoVo = this.getUserInfo(userPaidRecordVo.getUserId());
//            if (userInfoVo.getIsVip() == 1 && userInfoVo.getVipExpireTime().after(new Date())) {
//                isVip = true;
//            }
//
//
//            UserVipService userVipService = new UserVipService();
//            VipServiceConfig vipServiceConfig = vipServiceConfigMapper.selectById(userPaidRecordVo.getItemIdList().get(0));
//            Date now = new Date();
//            Integer serviceMonth = vipServiceConfig.getServiceMonth();
//            if (!isVip) {
//                //3.2 封装购买记录
//                //3.2.1 封装购买记录
//                //3.2.2 封装用户信息
//                userVipService.setStartTime(now);
//                DateTime dateTime = DateUtil.offsetMonth(now, serviceMonth);
//                userVipService.setExpireTime(dateTime);
//                //3.3 设置过期时间
//            } else {
//                userVipService.setStartTime(userInfoVo.getVipExpireTime());
//                userVipService.setExpireTime(DateUtil.offsetMonth(userInfoVo.getVipExpireTime(), serviceMonth));
//            }
//            userVipService.setOrderNo(userPaidRecordVo.getOrderNo());
//            userVipService.setUserId(userPaidRecordVo.getUserId());
//            userVipServiceMapper.insert(userVipService);
//            //3.4发放权益
//            userInfoVo.setIsVip(1);
//            userInfoVo.setVipExpireTime(userVipService.getExpireTime());
//            UserInfo userInfo = BeanUtil.copyProperties(userInfoVo, UserInfo.class);
//            userInfoMapper.updateById(userInfo);
//        }
    }

    /**
     * 更新VIP状态：处理过期会员
     *
     * @return
     */
    @Override
    public void updateVipExpireStatus(Date date) {
        //1.查询用户vip为1的状态的用户
        List<UserInfo> userInfos = userInfoMapper.selectList(
                new LambdaQueryWrapper<UserInfo>()
                        .eq(UserInfo::getIsVip, 1)
                        .lt(UserInfo::getVipExpireTime, date)
        );
        userInfos.stream().forEach(userInfo -> {
            userInfo.setIsVip(0);
            userInfoMapper.updateById(userInfo);
        });
    }
}
